package com.douguo.recipe.provider;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import org.apache.http.client.utils.URIUtils;

import com.douguo.recipe.network.Constant;
import com.douguo.recipe.object.Caipin;
import com.douguo.recipe.object.Caipu;
import com.douguo.recipe.object.Caixi;
import com.douguo.recipe.object.Favor;
import com.douguo.recipe.object.Kouwei;
import com.douguo.recipe.object.Nandu;
import com.douguo.recipe.object.Sort;
import com.douguo.recipe.object.Step;
import com.douguo.recipe.object.Tese;
import com.douguo.recipe.object.Calendar;

import com.douguo.recipe.provider.Documents.Recipes;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;

public class DBHelper {
	private Context mContext;
	private ContentResolver mContentResolver;

	public DBHelper(Context context) {
		mContext = context;
		mContentResolver = mContext.getContentResolver();

	}

	public void addRecipe(Caipu caipu) {
		ContentValues cvs = new ContentValues();
		cvs.put(Documents.Recipes._ID, caipu.id);
		cvs.put(Documents.Recipes.AUTHOR_NAME, caipu.author);
		cvs.put(Documents.Recipes.CAIPIN_ID, caipu.caipin.id);
		cvs.put(Documents.Recipes.CAIXI_ID, caipu.caixi.id);
		cvs.put(Documents.Recipes.TIME, caipu.time);
		cvs.put(Documents.Recipes.KOUWEI_ID, caipu.kouwei.id);
		cvs.put(Documents.Recipes.MAIN, caipu.major);
		cvs.put(Documents.Recipes.MINOR, caipu.minor);
		cvs.put(Documents.Recipes.NAME, caipu.name);
		cvs.put(Documents.Recipes.NANDU_ID, caipu.nandu.id);
		cvs.put(Documents.Recipes.THUMB, caipu.thumbPath);
		cvs.put(Documents.Recipes.PIC, caipu.photoPath);
		cvs.put(Documents.Recipes.TESE_ID, caipu.tese.id);
		cvs.put(Documents.Recipes.TIPS, caipu.tips);
		addSteps(caipu);
		mContentResolver.insert(Documents.Recipes.CONTENT_URI, cvs);
	}

	private void addSteps(Caipu caipu) {
		if (caipu != null) {
			ContentValues[] cvs = new ContentValues[caipu.steps.size()];
			int i = 0;

			for (Step step : caipu.steps) {
				cvs[i] = new ContentValues();
				cvs[i].put(Documents.Steps.DESCRIPT, step.content);
				cvs[i].put(Documents.Steps.NUMBER, i + 1);
				// cvs[i].put(Documents.Steps.PIC, value)
				cvs[i].put(Documents.Steps.RECIPE_ID, caipu.id);
				i++;
			}
			mContentResolver.bulkInsert(Documents.Steps.CONTENT_URI, cvs);
			// mContentResolver.insert(Documents.Steps.CONTENT_URI, values)
		}
	}
	
	List<Caixi> caixiSort = new LinkedList<Caixi>();
	List<Caipin> caipinSort = new LinkedList<Caipin>();
	List<Kouwei> kouweiSort = new LinkedList<Kouwei>();
	List<Tese> teseSort = new LinkedList<Tese>();
	List<Nandu> nanduSort = new LinkedList<Nandu>();

	

	// @PARAM sort to be added
	// @RETURN created row uri ,null while insert fail
	public Uri addSort(Sort sort) {
		ContentValues cvs = new ContentValues();
		String fieldId = "_id";
		String fieldName = null;
		String fieldPicPath = null;
		String fieldOrder = null;
		Uri uri = null;
		if (sort instanceof Caixi) {
			fieldName = Documents.Caixi.NAME;
			fieldPicPath = Documents.Caixi.IMAGE;
			uri = Documents.Caixi.CONTENT_URI;
			fieldOrder = Documents.Caixi.ORDER;
		} else if (sort instanceof Caipin) {
			fieldName = Documents.Caipin.NAME;
			fieldPicPath = Documents.Caipin.IMAGE;
			uri = Documents.Caipin.CONTENT_URI;
			fieldOrder = Documents.Caipin.ORDER;
		} else if (sort instanceof Kouwei) {
			fieldName = Documents.Kouwei.NAME;
			fieldPicPath = Documents.Kouwei.IMAGE;
			fieldOrder = Documents.Kouwei.ORDER;
			uri = Documents.Kouwei.CONTENT_URI;
		} else if (sort instanceof Tese) {
			fieldName = Documents.Tese.NAME;
			fieldPicPath = Documents.Tese.IMAGE;
			fieldOrder = Documents.Tese.ORDER;
			uri = Documents.Tese.CONTENT_URI;
		} else if (sort instanceof Nandu) {
			fieldName = Documents.Nandu.NAME;
			fieldPicPath = Documents.Nandu.IMAGE;
			fieldOrder = Documents.Nandu.ORDER;
			uri = Documents.Nandu.CONTENT_URI;
		}
		Uri row = null;
		if (uri != null) {
			cvs.put(fieldId, sort.id);
			cvs.put(fieldName, sort.name);
			cvs.put(fieldPicPath, sort.picId);
			cvs.put(fieldOrder, sort.order);
			row = mContentResolver.insert(uri, cvs);
		}
		return row;
	}

	public void updateRecipeThumb(Caipu caipu) {
		Uri uri = ContentUris.withAppendedId(Documents.Recipes.CONTENT_URI,
				Long.valueOf(caipu.id));
		ContentValues cvs = new ContentValues();
		cvs.put(Documents.Recipes.THUMB, caipu.thumbPath);
		mContentResolver.update(uri, cvs, null, null);
	}
	
	public void updateRecipePhoto(Caipu caipu) {
		Uri uri = ContentUris.withAppendedId(Documents.Recipes.CONTENT_URI,
				Long.valueOf(caipu.id));
		ContentValues cvs = new ContentValues();
		cvs.put(Documents.Recipes.PIC, caipu.photoPath);
		mContentResolver.update(uri, cvs, null, null);
	}

	public void deleteRecipe(Caipu caipu) {
		Uri uri = ContentUris.withAppendedId(Documents.Recipes.CONTENT_URI,
				Long.valueOf(caipu.id));
		mContentResolver.delete(uri, null, null);
	}

	public boolean hasFavor(Caipu caipu) {
		Cursor cursor = mContentResolver.query(Documents.Favor.CONTENT_URI,
				null, Documents.Favor.RECIPE_ID + "=?",
				new String[] { caipu.id }, null);
		if (cursor.getCount() > 0) {
			cursor.close();
			return true;
		}
		cursor.close();
		return false;
	}

	public boolean hasSorts() {
		Cursor cursor = mContentResolver.query(Documents.Caixi.CONTENT_URI,
				null, null, null, null);
		if (cursor.getCount() == 0) {
			cursor.close();
			return false;
		}
		cursor.close();
		cursor = mContentResolver.query(Documents.Caipin.CONTENT_URI, null,
				null, null, null);
		if (cursor.getCount() == 0) {
			cursor.close();
			return false;
		}
		cursor.close();
		cursor = mContentResolver.query(Documents.Kouwei.CONTENT_URI, null,
				null, null, null);
		if (cursor.getCount() == 0) {
			cursor.close();
			return false;
		}
		cursor.close();
		cursor = mContentResolver.query(Documents.Nandu.CONTENT_URI, null,
				null, null, null);
		if (cursor.getCount() == 0) {
			cursor.close();
			return false;
		}
		cursor.close();
		cursor = mContentResolver.query(Documents.Tese.CONTENT_URI, null, null,
				null, null);
		if (cursor.getCount() == 0) {
			cursor.close();
			return false;
		}
		cursor.close();
		return true;
	}

	public boolean hasRecipe(Caipu caipu) {
		Uri uri = ContentUris.withAppendedId(Documents.Recipes.CONTENT_URI,
				Long.valueOf(caipu.id));
		Cursor cursor = mContentResolver.query(uri, null, null, null, null);
		if (cursor.getCount() > 0) {
			cursor.close();
			return true;
		}
		cursor.close();
		return false;
	}

	// maybe return null
	public Caipu getRecipe(String recipeId) {
		Uri uri = ContentUris.withAppendedId(Documents.Recipes.CONTENT_URI,
				Long.valueOf(recipeId));
		Cursor cursor = mContentResolver.query(uri, null, null, null, null);
		Caipu caipu = null;
		if (cursor.moveToFirst()) {
			caipu = new Caipu();
			caipu.id = getString(cursor, Recipes._ID);
			caipu.caipin = new Caipin(getString(cursor, Recipes.CAIPIN_ID));
			caipu.caixi = new Caixi(getString(cursor, Recipes.CAIXI_ID));
			caipu.author = getString(cursor, Recipes.AUTHOR_NAME);
			caipu.kouwei = new Kouwei(getString(cursor, Recipes.KOUWEI_ID));
			caipu.major = getString(cursor, Recipes.MAIN);
			caipu.minor = getString(cursor, Recipes.MINOR);
			caipu.name = getString(cursor, Recipes.NAME);
			caipu.nandu = new Nandu(getString(cursor, Recipes.NANDU_ID));
			caipu.thumbPath = getString(cursor, Recipes.THUMB);
			caipu.photoPath = getString(cursor, Recipes.PIC);
			caipu.steps = getSteps(caipu);
			caipu.tese = new Tese(getString(cursor, Recipes.TESE_ID));
			caipu.time = getString(cursor, Recipes.TIME);
			caipu.tips = getString(cursor, Recipes.TIPS);
		}
		cursor.close();
		return caipu;
	}

	public List<Caipu> getRandomCaipuList(int maxNumber) {
		List<Caipu> recipes = new ArrayList<Caipu>();
		Cursor cursor = mContentResolver.query(Documents.Recipes.CONTENT_URI,
				null, null, null, Documents.Recipes.RANDOM_SORT_ORDER);
		cursor.moveToFirst();
		int i = 0;
		while (!cursor.isAfterLast() && i < maxNumber) {
			Caipu recipe = new Caipu();
			recipe.id = getString(cursor, Documents.Recipes._ID);
			recipe.name = getString(cursor, Documents.Recipes.NAME);
			recipe.major = getString(cursor, Documents.Recipes.MAIN);
			recipe.minor = getString(cursor, Documents.Recipes.MINOR);
			recipe.author = getString(cursor, Documents.Recipes.AUTHOR_NAME);
			recipe.thumbPath = getString(cursor, Documents.Recipes.THUMB);
			recipe.photoPath = getString(cursor, Documents.Recipes.PIC);
			recipes.add(recipe);
			i++;
			cursor.moveToNext();
		}
		cursor.close();
		return recipes;
	}

	public List<Caipu> getRecipeList(int[] types, String[] ids, String keywords) {
		List<Caipu> recipes = new ArrayList<Caipu>();
		StringBuilder selection = new StringBuilder();
		if (types != null) {
			for (int type : types) {
				if (selection.length() > 0) {
					selection.append(" AND ");
				}
				switch (type) {
				case Constant.TYPE_CAIPIN:
					selection.append(Documents.Recipes.CAIPIN_ID + "=?");
					break;
				case Constant.TYPE_CAIXI:
					selection.append(Documents.Recipes.CAIXI_ID + "=?");
					break;
				case Constant.TYPE_KOUWEI:
					selection.append(Documents.Recipes.KOUWEI_ID + "=?");
					break;
				case Constant.TYPE_TESE:
					selection.append(Documents.Recipes.TESE_ID + "=?");
					break;
				}
			}
		}
		if (keywords != null && keywords.length() > 0) {

			if (selection.length() > 0) {
				selection.append(" AND ");
			}
			selection.append(Documents.Recipes.NAME + " LIKE '%" + keywords
					+ "%'");
			// selection.append(" OR " + Documents.Recipes.MAIN + " LIKE "
			// + keywords);
			// selection.append(" OR " + Documents.Recipes.MINOR + " LIKE "
			// + keywords);
		}
		Cursor cursor = mContentResolver.query(Documents.Recipes.CONTENT_URI,
				null, selection.toString(), ids, null);// order null
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Caipu recipe = new Caipu();
			recipe.id = getString(cursor, Documents.Recipes._ID);
			recipe.name = getString(cursor, Documents.Recipes.NAME);
			recipe.major = getString(cursor, Documents.Recipes.MAIN);
			recipe.minor = getString(cursor, Documents.Recipes.MINOR);
			recipe.author = getString(cursor, Documents.Recipes.AUTHOR_NAME);
			recipe.thumbPath = getString(cursor, Documents.Recipes.THUMB);
			recipe.photoPath = getString(cursor, Documents.Recipes.PIC);
			recipes.add(recipe);
			cursor.moveToNext();
		}
		cursor.close();
		return recipes;
	}

	private List<Step> getSteps(Caipu caipu) {
		// TODO д������
		List<Step> steps = new ArrayList<Step>();
		Cursor cursor = mContentResolver.query(Documents.Steps.CONTENT_URI,
				null, Documents.Steps.RECIPE_ID + "=?",
				new String[] { caipu.id }, Documents.Steps.SORT_NUMBER_ORDER);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Step step = new Step();
			step.caipu = caipu;
			step.content = getString(cursor, Documents.Steps.DESCRIPT);
			step.id = getString(cursor, Documents.Steps._ID);
			steps.add(step);
			cursor.moveToNext();
		}
		cursor.close();
		return steps;
	}

	// @RETURN null while not found sort
	public String getSortName(Sort sort) {
		Uri uri = null;
		String fieldName = null;
		if (sort instanceof Caixi) {
			uri = Documents.Caixi.CONTENT_URI;
			fieldName = Documents.Caixi.NAME;
		} else if (sort instanceof Caipin) {
			uri = Documents.Caipin.CONTENT_URI;
			fieldName = Documents.Caipin.NAME;
		} else if (sort instanceof Kouwei) {
			uri = Documents.Kouwei.CONTENT_URI;
			fieldName = Documents.Kouwei.NAME;
		} else if (sort instanceof Tese) {
			uri = Documents.Tese.CONTENT_URI;
			fieldName = Documents.Tese.NAME;
		} else if (sort instanceof Nandu) {
			uri = Documents.Nandu.CONTENT_URI;
			fieldName = Documents.Nandu.NAME;
		}
		uri = ContentUris.withAppendedId(uri, Long.valueOf(sort.id));
		Cursor cursor = mContentResolver.query(uri, null, null, null, null);
		cursor.moveToFirst();
		String sortName = null;
		if (cursor.getCount() > 0) {
			sortName = getString(cursor, fieldName);
		}
		cursor.close();
		return sortName;
	}

	public List<Sort> getSorts(int type) {
		List<Sort> sorts = new ArrayList<Sort>();
		Uri uri = null;
		String fieldName = null;
		String fieldOrder = null;
		String fieldPicId = null;
		switch (type) {
		case Constant.TYPE_CAIXI:
			uri = Documents.Caixi.CONTENT_URI;
			fieldName = Documents.Caixi.NAME;
			fieldPicId = Documents.Caixi.IMAGE;
			fieldOrder = Documents.Caixi.DEFAULT_SORT_ORDER;
			break;
		case Constant.TYPE_CAIPIN:
			uri = Documents.Caipin.CONTENT_URI;
			fieldName = Documents.Caipin.NAME;
			fieldPicId = Documents.Caipin.IMAGE;
			fieldOrder = Documents.Caipin.DEFAULT_SORT_ORDER;
			break;
		case Constant.TYPE_KOUWEI:
			uri = Documents.Kouwei.CONTENT_URI;
			fieldName = Documents.Kouwei.NAME;
			fieldPicId = Documents.Kouwei.IMAGE;
			fieldOrder = Documents.Kouwei.DEFAULT_SORT_ORDER;
			break;
		case Constant.TYPE_TESE:
			uri = Documents.Tese.CONTENT_URI;
			fieldName = Documents.Tese.NAME;
			fieldPicId = Documents.Tese.IMAGE;
			fieldOrder = Documents.Tese.DEFAULT_SORT_ORDER;
			break;
		}
		Cursor cursor = mContentResolver.query(uri, null, null, null,
				fieldOrder);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Sort sort = new Sort();
			sort.name = getString(cursor, fieldName);
			sort.id = getString(cursor, Documents.Tese._ID);
			sort.picId = getString(cursor, fieldPicId);
			sorts.add(sort);
			cursor.moveToNext();
		}
		cursor.close();
		return sorts;
	}

	public List<Favor> getFavors() {
		List<Favor> favors = new ArrayList<Favor>();
		Cursor cursor = mContentResolver.query(Documents.Favor.CONTENT_URI,
				null, null, null, null);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Favor favor = new Favor();
			favor.mFavorId = getString(cursor, Documents.Favor.RECIPE_ID);
			favor.mRecipeId = getString(cursor, Documents.Favor.RECIPE_ID);
			favors.add(favor);
			cursor.moveToNext();
		}
		cursor.close();
		return favors;
	}

	public boolean addFavor(Caipu caipu) {
		if (!hasFavor(caipu)) {
			ContentValues cv = new ContentValues();
			cv.put(Documents.Favor.DATE, System.currentTimeMillis());
			cv.put(Documents.Favor.RECIPE_ID, caipu.id);
			mContentResolver.insert(Documents.Favor.CONTENT_URI, cv);
			return true;
		}
		return false;
	}

	public boolean deleteFavor(long recipeId) {
		if (mContentResolver.delete(Documents.Favor.CONTENT_URI,
				Documents.Favor.RECIPE_ID + "=?",
				new String[] { String.valueOf(recipeId) }) > 0)
			return true;
		return false;
	}

	public boolean addCalendar(Caipu caipu, int year, int month, int day) {
		if (!hasCalendar(year, month, day)) {
			ContentValues cv = new ContentValues();
			cv.put(Documents.Calendar.YEARMONTH,
					String.valueOf(year) + String.valueOf(month));
			cv.put(Documents.Calendar.RECIPE_ID, caipu.id);
			cv.put(Documents.Calendar.DATE, String.valueOf(day));
			mContentResolver.insert(Documents.Calendar.CONTENT_URI, cv);
			return true;
		}
		return false;
	}

	public boolean deleteCalendar(String calendarId) {
		Uri uri = ContentUris.withAppendedId(Documents.Calendar.CONTENT_URI,
				Long.valueOf(calendarId));
		if (mContentResolver.delete(uri, null, null) > 0)
			return true;
		return false;
	}

	public boolean updateCalendar(Caipu caipu, int year, int month, int day) {
		ContentValues cv = new ContentValues();
		cv.put(Documents.Calendar.RECIPE_ID, caipu.id);
		String selection = Documents.Calendar.YEARMONTH + "=? AND "
				+ Documents.Calendar.DATE + "=?";
		String[] selectionArgs = new String[] {
				String.valueOf(year) + String.valueOf(month),
				String.valueOf(day) };
		if (mContentResolver.update(Documents.Calendar.CONTENT_URI, cv,
				selection, selectionArgs) > 0)
			return true;
		return false;
	}

	public List<Calendar> getCalendars(int year, int month) {
		List<Calendar> calendars = new ArrayList<Calendar>();
		String selection = Documents.Calendar.YEARMONTH + "=?";
		String[] selectionArgs = new String[] { String.valueOf(year)
				+ String.valueOf(month) };
		Cursor cursor = mContentResolver.query(Documents.Calendar.CONTENT_URI,
				null, selection, selectionArgs, null);
		cursor.moveToFirst();
		while (!cursor.isAfterLast()) {
			Calendar calendar = new Calendar();
			calendar.mYearmonth = getString(cursor,
					Documents.Calendar.YEARMONTH);
			calendar.mDay = getString(cursor, Documents.Calendar.DATE);
			;
			calendar.mId = getString(cursor, Documents.Calendar._ID);
			;
			calendar.mRecipeId = getString(cursor, Documents.Calendar.RECIPE_ID);
			;
			calendars.add(calendar);
			cursor.moveToNext();
		}
		cursor.close();
		return calendars;
	}

	public boolean hasCalendar(int year, int month, int day) {
		String selection = Documents.Calendar.YEARMONTH + "=? AND "
				+ Documents.Calendar.DATE + "=?";
		String[] selectionArgs = new String[] {
				String.valueOf(year) + String.valueOf(month),
				String.valueOf(day) };
		Cursor cursor = mContentResolver.query(Documents.Calendar.CONTENT_URI,
				null, selection, selectionArgs, null);
		if (cursor.getCount() > 0) {
			cursor.close();
			return true;
		}
		cursor.close();
		return false;
	}

	private String getString(Cursor cursor, String filename) {
		String value = null;
		if (cursor != null) {
			value = cursor.getString(cursor.getColumnIndex(filename));
		}
		return value;
	}

	public List<Sort> getRandomSort(Sort sort, int num) {
		Uri uri = null;
		if (sort instanceof Caixi) {
			uri = Documents.Caixi.CONTENT_URI;
		} else if (sort instanceof Caipin) {
			uri = Documents.Caipin.CONTENT_URI;
		} else if (sort instanceof Kouwei) {
			uri = Documents.Kouwei.CONTENT_URI;
		} else if (sort instanceof Tese) {
			uri = Documents.Tese.CONTENT_URI;
		}
		Cursor cursor = mContentResolver.query(uri, null, null, null,
				"RANDOM()");
		List<Sort> sorts = null;
		String id;
		String name;
		cursor.moveToFirst();
		sorts = new ArrayList<Sort>();
		int i = 0;
		while (!cursor.isAfterLast() && i < num) {
			Sort newSort = null;
			id = getString(cursor, Documents.Caixi._ID);
			if (sort instanceof Caixi) {
				name = getString(cursor, Documents.Caixi.NAME);
				newSort = new Caixi(id, name);
			} else if (sort instanceof Caipin) {
				name = getString(cursor, Documents.Caipin.NAME);
				newSort = new Caipin(id, name);
			} else if (sort instanceof Kouwei) {
				name = getString(cursor, Documents.Kouwei.NAME);
				newSort = new Kouwei(id, name);
			} else if (sort instanceof Tese) {
				name = getString(cursor, Documents.Tese.NAME);
				newSort = new Tese(id, name);
			}
			sorts.add(newSort);
			i++;
			cursor.moveToNext();
		}
		cursor.close();
		return sorts;
	}

}
